/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package co.edu.eam.clinica.vista.gui.common;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.table.DefaultTableModel;

/**
 *Metodo para generar un TableModel dada una lista de Objetos.
 * @author Camilo Andres
 */
public class OncologosTableModel<T> extends DefaultTableModel {

    /**
     * Lista que posee los datos con los que se generara el TableModel.
     */
    private List<T> datos;
    /**
     * Atributos de la clase con los que se quiere generar el tableModel, separados por coma
     */
    private String atributos;
    /**
     * Columnas con las que se nombrara el TableMOdel, separadas por coma.
     */
    private String columnas;
    /**
     * 
     */
    private Class clase;

    /**
     * Constructor
     * @param datos 
     */
    public OncologosTableModel(List<T> datos) {
        this.datos = datos;
    }

    /**
     * Metodo para llenar el TableMOdel.
     */
    public void inicializar() {
        String[] atrs = atributos.split(",");

        setColumnIdentifiers(columnas.split(","));
        if (datos != null) {
            for (Object object : datos) {
                if (clase == null) {
                    try {
                        addRow(obtenerAtributos(object, atrs));
                    } catch (Exception ex) {
                        Logger.getLogger(OncologosTableModel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }else{
                    
                    if(clase.isInstance(object)){
                        try {
                        addRow(obtenerAtributos(object, atrs));
                    } catch (Exception ex) {
                        Logger.getLogger(OncologosTableModel.class.getName()).log(Level.SEVERE, null, ex);
                    } 
                    }
                    
                }
            }
        }


    }

    /**
     * 
     * @param datos
     * @param atributos
     * @param columnas 
     */
    public OncologosTableModel(List<T> datos, String atributos, String columnas) {
        this.datos = datos;
        this.atributos = atributos;
        this.columnas = columnas;
        inicializar();
    }

    /**
     * 
     * @param datos
     * @param atributos
     * @param columnas 
     */
    public OncologosTableModel(Class clase, List<T> datos, String atributos, String columnas) {
        this.datos = datos;
        this.atributos = atributos;
        this.columnas = columnas;
        this.clase = clase;
        inicializar();
    }

    /*METODOS UTILITARIOS------------------------------------------------------------------*/
    public Object[] obtenerAtributos(Object objeto, String... parametros) throws Exception {

        ArrayList lista = new ArrayList();
        for (String parametro : parametros) {
            Object valor = getValor(parametro, objeto);
            if (valor instanceof Date) {
                valor = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(valor);
            }

//            if(valor instanceof Boolean){
//                if(valor.equals(Boolean.TRUE)){
//                    valor="Si";
//                }else{
//                    valor="No";
//                }
//                    
//                
//            }


            if (valor != null) {
                lista.add(valor);
            } else {
                lista.add("");
            }


        }
        return lista.toArray();

    }

    /**
     * Metodo para obtener el valor del atributo del objeto.
     * el atributo puede estar anidado dentro de otros objetos.
     * @param atributo noombre del atributo, de la forma nombre.nombre....
     * @param objeto objeto al cual se le quiere extraer el valor.
     * @return un objeto.
     * @throws Exception 
     */
    public Object getValor(String atributo, Object objeto) throws Exception {
        String attrs[] = atributo.split("\\.");
        Object res = null;
        for (String att : attrs) {
            res = obtenerAtributo(att, objeto);
            if (res == null) {
                break;
            } else {
                objeto = res;
            }
        }
        return res;
    }

    /**
     * Obtener el valor del atributo navegando por toda la jerarquia de clases.
     * @param parametro parametro
     * @param objeto objeto donde se busca.
     * @return
     * @throws Exception 
     */
    public Object obtenerAtributo(String parametro, Object objeto) throws Exception {

        String par = parametro.substring(0, 1).toUpperCase() + parametro.substring(1);
        String metodo = "get" + par;
        Method m = null;
        if (objeto != null) {
            Class clase = objeto.getClass();
            boolean encontrado = false;
            while (encontrado == false) {

                if (clase == null) {
                    return null;
                }

                try {
                    m = clase.getDeclaredMethod(metodo);
                    encontrado = true;
                } catch (Exception exc) {
                    clase = clase.getSuperclass();
                    encontrado = false;
                }

            }
            Object o = m.invoke(objeto);
            return o;
        }
        return null;
    }

    public String darFormato(String parametro) {

        String par = parametro.substring(0, 1).toUpperCase() + parametro.substring(1);
        return "get" + par;
    }
}
